package com.shengqin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shengqin.common.pojo.CommonPage;
import com.shengqin.config.CommonException;
import com.shengqin.entity.Classes;
import com.shengqin.entity.School;
import com.shengqin.entity.User;
import com.shengqin.entity.UserRelSchool;
import com.shengqin.mapper.SchoolMapper;
import com.shengqin.pojo.school.SchoolImportParam;
import com.shengqin.service.IClassesService;
import com.shengqin.service.ISchoolService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shengqin.service.IUserService;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 学校 服务实现类
 * </p>
 *
 * @author Rui.Zhou
 * @since 2023-12-05
 */
@Service
public class SchoolServiceImpl extends ServiceImpl<SchoolMapper, School> implements ISchoolService {

    @Resource
    private IClassesService classesService;
    @Resource
    private IUserService userService;
    @Resource
    private UserRelSchoolService userRelSchoolService;

    @Override
    public Page<School> getPage(CommonPage<School> pageParam) {
        QueryWrapper<School> wrapper = new QueryWrapper<>();
        School schoolParam = pageParam.getQueryParam();
        if (StringUtils.hasLength(schoolParam.getName())) {
            wrapper.lambda().like(School::getName, schoolParam.getName());
        }
        if (StringUtils.hasLength(schoolParam.getSchoolType())) {
            wrapper.lambda().like(School::getSchoolType, schoolParam.getSchoolType());
        }
        Object loginObj = StpUtil.getLoginId();
        if (!loginObj.toString().equalsIgnoreCase("1")) {
//            wrapper.lambda().in(School::getCreateUserId, loginObj.toString());
            List<School> schoolList = listByCreateUserId(loginObj.toString());
            if(!CollectionUtils.isEmpty(schoolList)){
                Set<String> schoolIdList = schoolList.stream().map(school -> school.getId().toString()).collect(Collectors.toSet());
                if (CollectionUtils.isEmpty(schoolParam.getSchoolIds())) {
                    schoolParam.setSchoolIds(schoolIdList);
                } else {
                    schoolParam.getSchoolIds().addAll(schoolIdList);
                }
            }
        }
        if (!CollectionUtils.isEmpty(schoolParam.getSchoolIds())) {
            wrapper.lambda().in(School::getId, schoolParam.getSchoolIds());
        }
        wrapper.lambda().orderByDesc(School::getId);
        Page<School> schoolPage = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());
        page(schoolPage, wrapper);
        buildRecords(schoolPage.getRecords());
        return schoolPage;
    }

    private List<School> listByCreateUserId(String userId) {
        QueryWrapper<School> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(School::getCreateUserId, userId);
        return list(wrapper);
    }

    private void buildRecords(List<School> records) {
        if (!CollectionUtils.isEmpty(records)) {
            List<Integer> schoolIds = records.stream().map(School::getId).collect(Collectors.toList());
            List<Classes> classesList = classesService.listBySchoolIds(schoolIds);
            Map<Integer, List<Classes>> schoolClassesMap = classesList.stream().collect(Collectors.groupingBy(Classes::getSchoolId));
            records.forEach(rec -> {
                rec.setClassesNum(schoolClassesMap.getOrDefault(rec.getId(), new ArrayList<>()).size());
            });
        }
    }

    @Override
    public School getByNameAndLoginId(String schoolName) {
        QueryWrapper<School> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(School::getName, schoolName);
        wrapper.lambda().eq(School::getCreateUserId, StpUtil.getLoginId().toString());
        return getOne(wrapper);
    }

    @Override
    public List<School> listByNames(Collection<String> schoolNames) {
        QueryWrapper<School> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(School::getName, schoolNames);
//        wrapper.lambda().eq(School::getCreateUserId, StpUtil.getLoginId().toString());
        return list(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean onBatchSave(List<SchoolImportParam> cachedDataList, Set<String> errorList) {
        List<School> schoolList = new ArrayList<>();
        Map<String, List<SchoolImportParam>> schoolNameMap = cachedDataList.stream().collect(Collectors.groupingBy(SchoolImportParam::getSchoolName));
        schoolNameMap.forEach((schoolName, schoolImportParams) -> {
            if (schoolImportParams.size() > 1) {
                errorList.add("EXCEL中学校名称【" + schoolName + "】已存在");
            }
        });
        if (!CollectionUtils.isEmpty(errorList)) {
            throw new CommonException(String.join(",", errorList));
        }
        List<School> hasedSchoolList = listByUserId(Integer.valueOf(StpUtil.getLoginIdAsString()));
        cachedDataList.forEach(schoolImportParam -> {
            School school = hasedSchoolList.stream().filter(s -> s.getName().trim().equals(schoolImportParam.getSchoolName().trim())).findFirst().orElse(null);
            if (school != null) {
                errorList.add("学校名称【" + schoolImportParam.getSchoolName() + "】已存在");
            } else {
                school = new School();
                school.setName(schoolImportParam.getSchoolName());
                school.setCreateUserId(Integer.valueOf(StpUtil.getLoginId().toString()));
                school.setCreateTime(LocalDateTime.now());
                if (StringUtils.hasLength(schoolImportParam.getSchoolTypeDesc())) {
                    List<String> typeList = getSchoolTypes(schoolImportParam);
                    school.setSchoolType(String.join(",", typeList));
                }
                if (StringUtils.hasLength(schoolImportParam.getAreas())) {
                    String[] areas = schoolImportParam.getAreas().split("/");
                    school.setProvince(areas[0]);
                    if (areas.length > 1) {
                        school.setCity(areas[1]);
                    }
                    if (areas.length >= 2) {
                        school.setArea(areas[2]);
                    }
                }
                schoolList.add(school);
            }
        });

        if (!CollectionUtils.isEmpty(errorList)) {
            throw new CommonException(String.join(",", errorList));
        }

        boolean saveOk = saveOrUpdateBatch(schoolList);
        if (saveOk) {
            try {
                Set<Long> userIdList = new HashSet<>();
                userIdList.add(1L);
                userIdList.add(Long.valueOf(StpUtil.getLoginId().toString()));
                List<User> users = userService.listByIds(userIdList);
                if (!CollectionUtils.isEmpty(users)) {
                    users.forEach(user -> schoolList.forEach(school -> {
                        UserRelSchool userRelSchool = new UserRelSchool();
                        userRelSchool.setUserId(user.getId());
                        userRelSchool.setSchoolId(school.getId());
                        userRelSchool.setSchoolName(school.getName());
                        userRelSchoolService.save(userRelSchool);
                    }));
                }
            } catch (Exception e) {
                log.error("导入学校数据报错", e);
                throw new CommonException("导入学校数据失败" + e.getMessage());
            }

        }

        return saveOk;
    }

    @Override
    public School getBySchoolName(String schoolName) {
        List<School> schoolList = listByUserId(Integer.valueOf(StpUtil.getLoginIdAsString()));
        return schoolList.stream().filter(school -> school.getName().trim().equals(schoolName.trim())).findFirst().orElse(null);
    }

    @Override
    public List<School> listByUserId(Integer userId) {
        List<UserRelSchool> userRelSchools = userRelSchoolService.listByUserId(userId);
        if(CollectionUtils.isEmpty(userRelSchools)){
            return new ArrayList<>();
        }
        return listByIds(userRelSchools.stream().map(UserRelSchool::getSchoolId).collect(Collectors.toSet()));
    }

    @NotNull
    private static List<String> getSchoolTypes(SchoolImportParam schoolImportParam) {
        String[] types = schoolImportParam.getSchoolTypeDesc().split(",");
        List<String> typeList = new ArrayList<>();
        for (String type : types) {
            if (type.equalsIgnoreCase("小学")) {
                typeList.add("1");
            } else if (type.equalsIgnoreCase("初中")) {
                typeList.add("2");
            } else if (type.equalsIgnoreCase("高中")) {
                typeList.add("3");
            } else if (type.equalsIgnoreCase("大学")) {
                typeList.add("4");
            }
        }
        return typeList;
    }
}
